﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SmsUI.DataBase;
using org.smslib;
using System.Threading;
using org.smslib.modem;
using System.Diagnostics;
using SMSCore;
using System.Threading.Tasks;
using SmsUI.SmsCore;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using DevExpress.XtraEditors;
using SmsUI.N77;
using org.smslib.threading;
using org.smslib.balancing;
namespace SmsUI.SmsHelper
{
    public class GatewayRes
    {
        public AGateway AGateway { get; set; }
        public Comm2IP.Comm2IP ComIP { get; set; }
        public DateTime FirstSendTime { get; set; }
        public int SendCount { get; set; }
        public int SuccCount { get; set; }
    }
    public class SmsHelper
    {
        public const string IsCallNum = "specialInput";
        private static readonly object sendLock = new object();
        private static readonly object initLock = new object();
        private static readonly object stopingLock = new object();
        int hasInit = 0;
        int comCount = 0;
        int isSending = 0;
        int isStoping = 0;
        public CancellationTokenSource cts = new CancellationTokenSource();
        public CancellationTokenSource checkNumCts = new CancellationTokenSource();
        public static SmsHelper Instance = new SmsHelper();
        smsdbDataSet.tb_SetDataTable setInfo = DbRules.Instance.GetSetInfo();
        smsdbDataSet.tb_ContentDataTable contentList = DbRules.Instance.GetContentTable();
        Dictionary<string, GatewayRes> resList = new Dictionary<string, GatewayRes>();

        public Dictionary<string, GatewayRes> ResList
        {
            get { return resList; }
            set { resList = value; }
        }
        public Service srv = Service.getInstance();
        Task<bool> initTask = null;
        Task sendTask = null;
        Task checkTask = null;
        string sendedId = "0";//初始发送的id值
        public bool Listening = false;//是否没有执行完invoke相关操作  
        public bool Closing = false;//是否正在关闭串口，执行Application.DoEvents，并阻止再次invoke  
        //public int QueueIndex
        //{
        //    get
        //    {
        //        lock (QueueIndexLock)
        //        {
        //            lock (SmsHelper.DicLock)
        //            {
        //                return QueueOutMessageDic.Count;
        //            }
        //        }
        //    }
        //}
        // public static readonly object QueueIndexLock = new object();
        public static readonly object DicLock = new object();
        public bool IsSendFlag = false;
        public bool IsCallFlag = false;
        public bool IsDailFlag = false;
        public bool AllowModifyComPortState()
        {
            if (srv.getServiceStatus() == Service.ServiceStatus.STOPPED)
            {
                return true;
            }
            return false;
        }
        private SmsHelper()
        {
        }
        public void PauseSend()
        {
            lock (sendLock)
            {
                isSending = 0;
                Monitor.Pulse(sendLock);
            }
        }
        public void AddUseGateWay()
        {
            foreach (smsdbDataSet.tb_SetRow row in DbRules.Instance.GetSetInfo())
            {
                if (row.State == "启用")
                {
                    try
                    {
                        if (ComHelper.Instance.CheckComPorts(row.PortNum, row.BTL))
                        {
                            SmsHelper.Instance.AddGateway(row.PortNum, row.BTL, row.MaType);
                        }
                        else
                        {
                            row.State = "无法启用";
                        }
                    }
                    catch (Exception ex)
                    {
                        DevExpress.XtraEditors.XtraMessageBox.Show("启用端口" + row.PortNum + "错误!");
                        continue;
                    }
                }
            }
            DbRules.Instance.UpdateSetInfo();
            DbRules.Instance.GetSetInfo().AcceptChanges();
        }
        public bool StartSend()
        {

            if (srv.getServiceStatus() == Service.ServiceStatus.STOPPED)
            {
                if (AysnInit())
                {

                    sendedId = "0";
                    cts.Dispose();
                    cts = new CancellationTokenSource();
                    sendTask = new Task(SendMsg);
                    sendTask.Start();
                }
                else
                {
                    return false;
                }
            }
            else
            {
                XtraMessageBox.Show("暂不能启动，请稍后再试！");
                return false;
            }
            lock (sendLock)
            {
                isSending = 1;
                Monitor.Pulse(sendLock);
            }
            return true;
        }
        public void ServiceStop()
        {
            if (isStoping == 1) return;
            lock (stopingLock)
            {
                isStoping = 1;
            }
            cts.Cancel();
            checkNumCts.Cancel();
            if (sendTask != null)
            {
                /// sendTask.Wait(5000, cts.Token);
            }

            while (true)
            {
                if (sendTask != null)
                {
                    if (sendTask.IsCompleted)
                    {
                        break;
                    }
                    else
                    {
                        sendTask.Wait(500);
                    }
                }
                else
                {
                    break;
                }
            }
            if (checkTask != null)
            {
                // checkTask.Wait(5000, checkNumCts.Token);
            }
            while (true)
            {
                if (checkTask != null)
                {
                    if (checkTask.IsCompleted)
                    {
                        break;
                    }
                    else
                    {
                        checkTask.Wait();
                    }
                }
                else
                {
                    break;
                }
            }
            // Thread.Sleep(5000);
            Closing = true;
            while (Listening) System.Windows.Forms.Application.DoEvents();
            //打开时点击，则关闭串口  
            try
            {

                srv.stopService();
            }
            catch (Exception ex)
            {
                Logger.Write(ex);
            }
            Closing = false;

            lock (initLock)
            {
                hasInit = 0;
            }
            //修改为只将pending的号码重写
            //将listview的数据重写回datatbale 清空pending列表
            // sendListForm sendListForm = ((sendListForm)FormManager.Instance.GetForm("SendListItem"));
            // sendListForm.ReWrite();
            try
            {
                if (srv.getQueueManager() != null)
                {
                    if (!srv.getQueueManager().removeAllPendingMessages())
                    {

                    }
                    srv.getQueueManager().stop();

                }
            }
            catch (Exception ex)
            {
                Logger.Write(ex);
            }

            //将检测号码的listview的数据重写回List
            //frmTrueTel frmTrueTel = ((frmTrueTel)FormManager.Instance.GetForm("TrueNumItem"));
            //frmTrueTel.BeginInvoke(new System.Windows.Forms.MethodInvoker(() =>
            //   frmTrueTel.ReWrite()));
            lock (SmsHelper.DicLock)
            {
                QueueOutMessageDic.Clear();
            }
            lock (stopingLock)
            {
                isStoping = 0;
            }
            RemoveAllGateway();
            while (true)
            {
                sendListForm f = ((sendListForm)FormManager.Instance.GetForm("SendListItem"));

                if (f.InputStatesLable.Text == "已完成")
                {
                    break;
                }

                Thread.Sleep(1000);
            }
        }
        public bool AysnInit()
        {
            RemoveAllGateway();
            AddUseGateWay();
            if (resList.Keys.Count == 0)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("请启用至少一个端口后再开始发送！");
                return false;
            }

            initTask = new Task<bool>(Init);
            initTask.Start();
            return true;
        }
        public bool Init()
        {
            srv.setInboundMessageNotification(new InboundNotification());
            srv.setOutboundMessageNotification(new MyOutboundNotification());
            srv.setCallNotification(new CallNotification());
            srv.setGatewayStatusNotification(new GatewayStatusNotification());
            srv.setQueueSendingNotification(new MyQueueSendingNotification());
            srv.setLoadBalancer(new MyBalance());
            srv.setRouter(new MyRouter());
            lock (comCountLock)
            {
                while (true)
                {
                    if (comCount == 0)
                    {
                        Monitor.Wait(comCountLock, 200);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            // srv.getSettings().CNMI_EMULATOR_INTERVAL = 150;
            srv.getSettings().QUEUE_DIRECTORY = "c:\\";
            srv.getSettings().SERIAL_TIMEOUT = 1000;
            srv.getSettings().QUEUE_RETRIES = 0;
            srv.getSettings().CNMI_EMULATOR_INTERVAL = 15;
            srv.getSettings().OUTBOUND_RETRIES = 6;
            srv.getSettings().OUTBOUND_RETRY_WAIT = 500;
            //  srv.getSettings().DISABLE_COPS = true;
            //    srv.getSettings().SERIAL_KEEPALIVE_INTERVAL = 5000;
            if (srv.getServiceStatus() == org.smslib.Service.ServiceStatus.STOPPED)
            {
                try
                {
                    srv.startService();
                }
                catch (Exception ex)
                {
                    Logger.Write(ex);
                    lock (initLock)
                    {
                        hasInit = 2;
                        Monitor.Pulse(initLock);
                    }
                    return false;
                }
                srv.getQueueManager().removeAllPendingMessages();
                lock (initLock)
                {
                    hasInit = 1;
                    isSending = 1;
                    Monitor.Pulse(initLock);
                }
            }
            return true;
        }
        private object comCountLock = new object();
        public bool AddGateway(string portNum, string BTL, string maType)
        {

            if (srv.getServiceStatus() != Service.ServiceStatus.STOPPED)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("发送状态下不能添加端口");
                return false;
            }
            if (resList.ContainsKey(portNum))
            {
                return false;
            }
            int iMatype = 0;
            int.TryParse(maType, out iMatype);
            if (!CheckDog.IsSupp(iMatype))
            {
                return false;
            }
            int btl = int.Parse(BTL);
            Comm2IP.Comm2IP com1 = new Comm2IP.Comm2IP(new byte[] { 127, 0, 0, 1 }, 12000 + comCount, portNum, btl);
            Thread t = new Thread(new ThreadStart(com1.Run));
            t.IsBackground = true;
            t.Start();
            IPModemGateway gateway = null;
            if (maType == "0")
            {
                gateway = new DTGS800IPModemGateway("" + portNum, "127.0.0.1", 12000 + comCount, "Wavecom", "");
            }
            if (maType == "1")
            {
                gateway = new WavecomModemGatewayCall("" + portNum, "127.0.0.1", 12000 + comCount, "Wavecom", "");
            }
            if (maType == "2")
            {
                gateway = new Q2385CModemGateway("" + portNum, "127.0.0.1", 12000 + comCount, "Wavecom", "");
                gateway.setIpProtocol(ModemGateway.IPProtocols.BINARY);
                //// Set the modem protocol to PDU (alternative is TEXT). PDU is the default, anyway...
                gateway.setProtocol(AGateway.Protocols.TEXT);
            }
            if (maType == "1" || maType == "0")
            {
                gateway.setIpProtocol(ModemGateway.IPProtocols.BINARY);
                // Set the modem protocol to PDU (alternative is TEXT). PDU is the default, anyway...
                gateway.setProtocol(AGateway.Protocols.PDU);
            }
            GatewayRes res = new GatewayRes();
            res.AGateway = gateway;
            res.ComIP = com1;
            if (!resList.ContainsKey(portNum))
            {
                resList.Add(portNum, res);
            }
            else
            {
                resList.Remove(portNum);
                resList.Add(portNum, res);
            }
            // Do we want the Gateway to be used for Inbound messages?
            gateway.setInbound(true);
            // Do we want the Gateway to be used for Outbound messages?
            gateway.setOutbound(true);
            // Let SMSLib know which is the SIM PIN.
            //gateway.setSimPin("0000");
            // Explicit SMSC address set is required for some modems.
            // Below is for VODAFONE GREECE - be sure to set your own!
            //+8613010112500
            string smsNum = ConfigManager.GetValue("smsNum");
            gateway.setSmscNumber(smsNum);
            //    useCount++;
            srv.addGateway(gateway);
            lock (comCountLock)
            {
                comCount++;
                Monitor.Pulse(comCountLock);
            }
            return true;
        }
        public void RemoveAllGateway()
        {
            if (srv.getServiceStatus() != Service.ServiceStatus.STOPPED)
            {

            }
            foreach (GatewayRes ag in resList.Values)
            {
                try
                {
                    srv.removeGateway(ag.AGateway);
                    ag.ComIP.Stop();
                }
                catch (Exception ex)
                {
                    Logger.Write(ex);
                }
            }
            for (java.util.Iterator iter = srv.getGateways().iterator(); iter.hasNext(); )
            {
                IPModemGateway str = (IPModemGateway)iter.next();
                srv.removeGateway(str);
            }
            resList.Clear();
        }
        //public bool RemoveGateway(string portNum)
        //{
        //    if (srv.getServiceStatus() != Service.ServiceStatus.STOPPED)
        //    {
        //        DevExpress.XtraEditors.XtraMessageBox.Show("发送状态下不能移除端口");
        //        return false;
        //    }
        //    if (!string.IsNullOrEmpty(portNum) && resList.ContainsKey(portNum))
        //    {
        //        try
        //        {
        //            srv.removeGateway(resList[portNum].AGateway);
        //            resList.Remove(portNum);
        //            return true;
        //        }
        //        catch (Exception ex)
        //        {
        //            Logger.Write(ex);
        //            return false;
        //        }
        //    }
        //    return false;
        //}
        public bool AsynCheckNum()
        {
            bool re;
            if (re = AysnInit())
            {
                checkNumCts.Dispose();
                checkNumCts = new CancellationTokenSource();
                checkTask = new Task(CheckNum);
                checkTask.Start();
            }
            return re;
        }
        public void CheckNum()
        {
            SendCount = 0;
            try
            {
                DbRules.Instance.UpdateAllSendStates();
                while (true)
                {
                    if (checkNumCts.IsCancellationRequested)
                    {
                        break;
                    }
                    lock (initLock)
                    {
                        while (true)
                        {
                            if (hasInit == 0)
                            {
                                if (checkNumCts.IsCancellationRequested)
                                {
                                    break;
                                }
                                Monitor.Wait(initLock, 200);
                            }
                            else
                            {
                                break;
                            }
                        }
                        ///初始化错误
                        if (hasInit == 2)
                        {
                            Logger.Write("hasInif=2初始化错误！");
                            return;
                        }
                    }
                    sendedId = "1";
                    while (true)
                    {
                        try
                        {
                            Thread.Sleep(100);
                            lock (sendLock)
                            {
                                if (checkNumCts.IsCancellationRequested)
                                {
                                    break;
                                }
                                while (true)
                                {
                                    if (checkNumCts.IsCancellationRequested)
                                    {
                                        break;
                                    }
                                    if (isSending == 0)
                                    {
                                        Monitor.Wait(sendLock, 200);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                //增加一个策略 当队列中的待发送短信数大于2倍端口数时 停止向队列中加入短信
                                bool needAddtoQueue = false;
                                int count = 0;
                                while (!needAddtoQueue)
                                {
                                    int pendingMessageCount = 0;
                                    if (checkNumCts.IsCancellationRequested)
                                    {
                                        break;
                                    }
                                    for (int i = 0; i < resList.Keys.Count; i++)
                                    {
                                        pendingMessageCount += srv.getQueueManager().pendingQueueSize(resList.Keys.ElementAt<string>(i));
                                    }
                                    if (pendingMessageCount < (resList.Count * 1))
                                    {
                                        needAddtoQueue = true;
                                    }
                                    Thread.Sleep(200);
                                    count++;
                                    if (count > 20)
                                    {
                                        count = 0;
                                        // Console.WriteLine("等待Pending:" + count);
                                    }
                                }
                            }
                            if (checkNumCts.IsCancellationRequested)
                            {
                                break;
                            }
                            //Console.WriteLine("发送开始!!");
                            string phoneNum = "";
                            string specialPort = "";
                            int pority = 5;
                            string content = SmsHelper.IsCallNum;
                            // smsdbDataSet.tb_CheckListDataTable sendList = DbRules.Instance.GetNeedCheckInfo();
                            phoneNum = ((frmTrueTel)FormManager.Instance.GetForm("TrueNumItem")).GetANum();
                            Console.WriteLine("取出" + phoneNum);
                            //if (sendList.Rows.Count > 0)
                            //{

                            //int rowCount = DbRules.Instance.UpdateSendStates(int.Parse(sendedId), "1");
                            //if (rowCount != 1)
                            //{
                            //    Console.WriteLine("更新节点状态影响行数" + rowCount);
                            //}
                            // phoneNum = sendList[0].PhoneNum;
                            //Console.WriteLine("输出号码:" + phoneNum);
                            if (phoneNum == "" || phoneNum == "\"\"" || phoneNum == "1234567890")
                            {

                                continue;
                            }

                            //}
                            //else
                            //{
                            //    continue;
                            //}
                            OutboundMessage msg = new OutboundMessage(phoneNum, content);
                            msg.setEncoding(Message.MessageEncodings.ENCUCS2);
                            msg.setId(sendedId.ToString());
                            msg.setPriority(10 - pority);
                            if (!string.IsNullOrEmpty(specialPort))
                            {
                                msg.setGatewayId(specialPort);
                            }
                            if (checkNumCts.IsCancellationRequested)
                            {
                                break;
                            }
                            bool result = srv.queueMessage(msg);
                            if (result == false)
                            {
                                Thread.Sleep(2000);
                                ((frmTrueTel)FormManager.Instance.GetForm("TrueNumItem")).AddNum(phoneNum);
                                //Console.WriteLine("队列详细失败");
                            }
                            else
                            {
                                SendCount++;
                                //  sendList.Rows[0].Delete();
                                //   DbRules.Instance.UpdateSendList();
                                lock (SmsHelper.DicLock)
                                {
                                    int intId = int.Parse(sendedId);
                                    QueueOutMessageDic.Add((intId++).ToString(), msg);
                                    sendedId = intId.ToString();
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Write("SendMsg主循环异常" + ex.ToString());
                            continue;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Write("SendMsg错误" + ex.ToString());
            }
        }
        public Dictionary<string, OutboundMessage> QueueOutMessageDic = new Dictionary<string, OutboundMessage>();
        public static int SendCount = 0;
        public static int StartID = -1;
        public static bool IsFirstID = false;
        public void SendMsg()
        {
            IsFirstID = false;
            SendCount = 0;
            try
            {
                DbRules.Instance.UpdateAllSendStates();
                while (true)
                {
                    if (cts.IsCancellationRequested)
                    {
                        break;
                    }
                    lock (initLock)
                    {
                        while (true)
                        {
                            if (hasInit == 0)
                            {
                                if (cts.IsCancellationRequested)
                                {
                                    break;
                                }
                                Monitor.Wait(initLock, 200);
                            }
                            else
                            {
                                break;
                            }
                        }
                        ///初始化错误
                        if (hasInit == 2)
                        {
                            Logger.Write("hasInif=2初始化错误！");
                            return;
                        }
                    }
                    sendedId = "0";
                    while (true)
                    {
                        try
                        {
                            Thread.Sleep(100);
                            lock (sendLock)
                            {
                                if (cts.IsCancellationRequested)
                                {
                                    break;
                                }
                                while (true)
                                {
                                    if (cts.IsCancellationRequested)
                                    {
                                        break;
                                    }
                                    if (isSending == 0)
                                    {
                                        Monitor.Wait(sendLock, 200);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                //增加一个策略 当队列中的待发送短信数大于2倍端口数时 停止向队列中加入短信
                                bool needAddtoQueue = false;
                                int count = 0;
                                while (!needAddtoQueue)
                                {
                                    int pendingMessageCount = 0;
                                    if (cts.IsCancellationRequested)
                                    {
                                        break;
                                    }
                                    for (int i = 0; i < resList.Keys.Count; i++)
                                    {
                                        pendingMessageCount += srv.getQueueManager().pendingQueueSize(resList.Keys.ElementAt<string>(i));
                                    }
                                    if (pendingMessageCount < (resList.Count * 2))
                                    {
                                        needAddtoQueue = true;
                                    }
                                    Thread.Sleep(200);
                                    count++;
                                    if (count > 20)
                                    {
                                        count = 0;

                                        // Console.WriteLine("等待Pending:" + count);
                                    }
                                }
                            }
                            if (cts.IsCancellationRequested)
                            {
                                break;
                            }
                            //Console.WriteLine("发送开始!!");
                            string phoneNum = "";
                            string specialPort = "";
                            int pority = 5;
                            string content = GetRandomContent();
                            if (string.IsNullOrWhiteSpace(content))
                            {
                                continue;
                            }

                            SendClass sc = ((sendListForm)FormManager.Instance.GetForm("SendListItem")).GetANum();
                            Console.WriteLine("取出" + sc.PhoneNum + " " + sc.ComPort + " " + sc.Content);
                            phoneNum = sc.PhoneNum;
                            //smsdbDataSet.tb_SendListDataTable sendList = DbRules.Instance.GetNeedSendInfo();
                            //if (sendList.Rows.Count > 0)
                            //{

                            //int rowCount = DbRules.Instance.UpdateSendStates(int.Parse(sendedId), "1");
                            //if (rowCount != 1)
                            //{
                            //    Console.WriteLine("更新节点状态影响行数" + rowCount);
                            //}

                            //Console.WriteLine("输出号码:" + phoneNum);
                            if (phoneNum == "" || phoneNum == "\"\"" || phoneNum == "1234567890")
                            {
                                //try
                                //{
                                //    DbRules.Instance.DeleteTempNumber();
                                //    //if (DbRules.Instance.DeleteSendListByID(sendList[0].ID.ToString()))
                                //    //{
                                //    //}
                                //    //else
                                //    //{
                                //    //    Logger.Write("删除不存在错误 " + phoneNum);
                                //    //}
                                //}
                                //catch (Exception ex)
                                //{
                                //    Logger.Write("删除2不存在错误 " + phoneNum);
                                //    Logger.Write(ex);
                                //    phoneNum = "13811878005";
                                //}
                                continue;
                            }
                            specialPort = sc.ComPort;

                            if (!string.IsNullOrEmpty(sc.Content))
                            {
                                content = sc.Content;
                            }
                            //}
                            //else
                            //{
                            //    continue;
                            //}
                            //if (ConfigManager.GetValue("factorySend") == "1")
                            //{
                            string orSendid = sendedId;
                            if (SendCount != 0 && SendCount % int.Parse(ConfigManager.GetValue("factoryCount")) == 0)
                            {
                                content = ConfigManager.GetValue("factoryContent");
                                content = "已发送条数" + SendCount;
                                phoneNum = ConfigManager.GetValue("factoryNum");
                                sendedId = "-" + sendedId;

                            }
                            //}
                            OutboundMessage msg = new OutboundMessage(phoneNum, content);
                            msg.setEncoding(Message.MessageEncodings.ENCUCS2);
                            msg.setId(sendedId.ToString());
                            msg.setPriority(10 - pority);
                            if (!string.IsNullOrEmpty(specialPort))
                            {
                                msg.setGatewayId(specialPort);
                            }
                            if (cts.IsCancellationRequested)
                            {
                                break;
                            }
                            bool result = srv.queueMessage(msg);
                            if (result == false)
                            {
                                ((sendListForm)FormManager.Instance.GetForm("SendListItem")).AddNum(phoneNum, "", "");
                                Thread.Sleep(2000);
                                //  DbRules.Instance.UpdateSendStates(int.Parse(orSendid), "0");
                                //Console.WriteLine("队列详细失败");
                            }

                            else
                            {
                                SendCount++;

                                //if (sendedId.IndexOf("-") > -1)
                                //{
                                //    DbRules.Instance.UpdateSendStates(int.Parse(orSendid), "0");
                                //}


                                //  sendList.Rows[0].Delete();
                                //   DbRules.Instance.UpdateSendList();
                                lock (SmsHelper.DicLock)
                                {
                                    QueueOutMessageDic.Add(SendCount.ToString(), msg);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Write("SendMsg主循环异常" + ex.ToString());
                            continue;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Write("SendMsg错误" + ex.ToString());
            }
        }
        public string GetRandomContent()
        {
            Random r = new Random();
            string content = "";
            try
            {
                int i = r.Next(0, contentList.Rows.Count);
                content = contentList[i].Content;
            }
            catch
            {
                return content;
            }
            string randomAdd = ConfigManager.GetValue("randomAdd");
            if (randomAdd == "1")
            {
                string randomAddString = ConfigManager.GetValue("randomAddString");
                string[] randomAddGroup = randomAddString.Split(',');
                int j = r.Next(0, randomAddGroup.Length);
                content += randomAddGroup[j];
            }
            return content;
        }
        internal bool RemoveQueueByID(string id)
        {
            bool resu = true;
            if (QueueOutMessageDic.ContainsKey(id))
            {
                OutboundMessage mess = QueueOutMessageDic[id];
                bool rea = srv.getQueueManager().removePendingMessage(mess);
                QueueOutMessageDic.Remove(id);
            }
            //if (resu == true)
            //{
            if (resu == true)
            {
                DbRules.Instance.DeleteSendListByID(id);
            }
            else
            {
            }
            return resu;
        }
        public void AysnDialNum(string comPort, string btl, string maType, string phoneNum)
        {
        }
        public void DialNum(string[] comPort, string[] btl, string[] maType, string phoneNum)
        {
            ProcessingForm proForm = new ProcessingForm();
            proForm.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            proForm.SetText("正在拨打，请稍后。。。");
            proForm.Show();
            Task dialNumTask = new Task(() =>
            {
                try
                {
                    //if (string.IsNullOrEmpty(comPort))
                    //{
                    //    XtraMessageBox.Show("请选择Com口!");
                    //    return;
                    //}
                    if (srv.getServiceStatus() != Service.ServiceStatus.STOPPED)
                    {
                        try
                        {
                            srv.stopService();
                        }
                        catch (Exception ex)
                        {
                            Logger.Write(ex);
                        }
                    }
                    RemoveAllGateway();
                    for (int i = 0; i < comPort.Length; i++)
                    {
                        if (ComHelper.Instance.CheckComPorts(comPort[i], btl[i]))
                        {
                            AddGateway(comPort[i], btl[i], maType[i]);
                        }
                        else
                        {
                            continue;
                        }
                    }
                    srv.startService();
                    for (int i = 0; i < comPort.Length; i++)
                    {
                        if (string.IsNullOrEmpty(comPort[i]))
                        {
                            continue;
                        }
                        OutboundMessage msg = new OutboundMessage(phoneNum, IsCallNum);
                        msg.setEncoding(Message.MessageEncodings.ENCUCS2);
                        msg.setId(sendedId.ToString());
                        msg.setPriority(0);
                        msg.setGatewayId(comPort[i]);
                        srv.sendMessage(msg);
                    }
                }
                catch (Exception ex)
                {
                    Logger.Write(ex);
                    XtraMessageBox.Show("拨打失败！");
                }
                finally
                {
                    try
                    {
                        try
                        {
                            srv.stopService();
                        }
                        catch
                        {
                        }
                        RemoveAllGateway();
                    }
                    catch
                    {
                    }
                }
            }
            );
            dialNumTask.Start();
            Action<Task> commit = (antecendent) =>
                FormManager.Instance.MainForm.BeginInvoke
                (new System.Windows.Forms.MethodInvoker(() => proForm.Close()));
            dialNumTask.ContinueWith(commit);
        }
    }
    public class MyOutboundNotification : IOutboundMessageNotification
    {
        public void process(AGateway ag, OutboundMessage om)
        {
            if (SmsHelper.Instance.Closing) return;//如果正在关闭，忽略操作，直接返回，尽快的完成串口监听线程的一次循环  
            try
            {
                SmsHelper.Instance.Listening = true;//设置标记，说明我已经开始处理数据，一会儿要使用系统UI的。  
                if (om.getText() == SmsHelper.IsCallNum)
                {
                    AddUseNumber(null, om);
                }
                else
                {
                    AddSendedMsg(null, om);
                }
            }
            finally
            {
                SmsHelper.Instance.Listening = false;//我用完了，ui可以关闭串口了。  
            }
        }
        public void AddUseNumber(AGateway ag, OutboundMessage om)
        {
            frmTrueTel f2 = ((frmTrueTel)FormManager.Instance.GetForm("TrueNumItem"));
            if (om.getMessageStatus() == OutboundMessage.MessageStatuses.SENT)
            {
                //DbRules.Instance.UpdateCheckStates(int.Parse(om.getId()), 1, 1);
                f2.Invoke(new System.Windows.Forms.MethodInvoker(() => f2.AddUseNum(om.getRecipient())));
            }
            else
            {
                f2.Invoke(new System.Windows.Forms.MethodInvoker(() => f2.AddUnUseNum(om.getRecipient())));
                //DbRules.Instance.DeleteChekcListByID(int.Parse(om.getId()));
                // f2.Invoke(new System.Windows.Forms.MethodInvoker(() => f2.AddUseNum(om.getRecipient())));
            }
        }
        public void AddSendedMsg(AGateway ag, OutboundMessage om)
        {
            //更新发件箱
            smsdbDataSet.tb_SendedListDataTable tb = null;
            SendedListForm f = ((SendedListForm)FormManager.Instance.GetForm("SendRecodItem"));
            f.Invoke(new System.Windows.Forms.MethodInvoker(() =>
            {
                //DbRules.Instance.SetSendingCount(om.getGatewayId(), 0);
                tb = DbRules.Instance.GetSendedListTable();
                if (tb.Rows.Count > 0)
                {
                    if (!SmsHelper.IsFirstID)
                    {
                        SmsHelper.StartID = tb[0].ID;
                    }
                    SmsHelper.IsFirstID = true;
                }
                for (int i = tb.Rows.Count - 1; i >= 0; i--)
                {
                    if (tb[i].PhoneNum == om.getRecipient() && tb[i].SendSet == om.getGatewayId() && tb[i].State == "未知")
                    {
                        if (om.getMessageStatus() == OutboundMessage.MessageStatuses.SENT)
                        {
                            tb[i].State = "成功";
                        }
                        else
                        {
                            tb[i].State = "失败";
                        }
                        DbRules.Instance.UpdateSendedList();
                        tb.AcceptChanges();
                        break;
                    }
                }
            }));
            //更新发送数量
            smsdbDataSet.tb_SetDataTable tbSet = null;
            SetManagerForm f2 = ((SetManagerForm)FormManager.Instance.GetForm("SetManagerItem"));
            f2.Invoke(new System.Windows.Forms.MethodInvoker(() =>
            {
                tbSet = DbRules.Instance.GetSetInfo();
                for (int i = 0; i < tbSet.Rows.Count; i++)
                {
                    if (tbSet[i].PortNum == om.getGatewayId())
                    {
                        if (om.getMessageStatus() == OutboundMessage.MessageStatuses.SENT)
                        {
                            tbSet[i].SuccessCount = tbSet[i].SuccessCount + 1;
                        }
                        else
                        {
                            tbSet[i].FailCount = tbSet[i].FailCount + 1;

                            SmsHelper.Instance.ResList[om.getGatewayId()].SendCount--;
                           
                        }
                        break;
                    }
                }
                SmsHelper.Instance.ResList[om.getGatewayId()].SuccCount--;
                DbRules.Instance.UpdateSetInfo();
                tbSet.AcceptChanges();
            }));
        }
    }
    public class CallNotification : ICallNotification
    {
        public void process(AGateway gateway, String callerId)
        {
            //System.Windows.Forms.MessageBox.Show(callerId);
            Debug.WriteLine(">>> New call detected from Gateway: " + gateway.getGatewayId() + " : " + callerId);
        }
    }
    public class InboundNotification : IInboundMessageNotification
    {
        public void process(AGateway gateway, org.smslib.Message.MessageTypes msgType, InboundMessage msg)
        {
            try
            {
                if (SmsHelper.Instance.Closing) return;//如果正在关闭，忽略操作，直接返回，尽快的完成串口监听线程的一次循环  
                SmsHelper.Instance.Listening = true;//设置标记，说明我已经开始处理数据，一会儿要使用系统UI的。
                smsdbDataSet.tb_ReciveListDataTable tb = null;
                if (msgType == org.smslib.Message.MessageTypes.INBOUND)
                {
                    ReciveListForm f = ((ReciveListForm)FormManager.Instance.GetForm("ReciveRecodItem"));
                    f.BeginInvoke(new System.Windows.Forms.MethodInvoker(() =>
                    {
                        tb = DbRules.Instance.GetReciveListTable();
                        java.util.Date jDate = msg.getDate();
                        DateTime cDate = DateTime.Now;
                        string text = "";
                        try
                        {
                            text = msg.getText();
                            string maType = DbRules.Instance.GetSetInfoMaType(gateway.getGatewayId());
                            string setType = "0";
                            if (!string.IsNullOrWhiteSpace(maType))
                            {
                                setType = maType;
                            }
                            if (setType == "2")
                            {
                                byte[] b = Encoding.BigEndianUnicode.GetBytes(text);
                                byte[] b2 = new byte[b.Length / 2];
                                int index = 0;
                                for (int i = 0; i < b.Length; i++)
                                {
                                    if (b[i] == 255)
                                    {
                                        b[i] = 0;
                                    }
                                    if (b[i] != 0)
                                    {
                                        b2[index] = b[i];
                                        index++;
                                    }
                                }
                                byte[] b3 = new byte[b.Length];
                                int b3Index = 0;
                                for (int i = 0; i < b.Length; )
                                {
                                    if (b[i + 1] >= 78)
                                    {
                                        if (i + 4 <= b.Length)
                                        {
                                            b3[b3Index] = b[i + 1];
                                            b3Index++;
                                            b3[b3Index] = b[i + 3];
                                            b3Index++;
                                            i = i + 4;
                                        }
                                        else
                                        {
                                            break;
                                        }
                                        continue;
                                    }
                                    if (i + 2 <= b.Length)
                                    {
                                        b3[b3Index] = b[i];
                                        b3Index++;
                                        b3[b3Index] = b[i + 1];
                                        b3Index++;
                                        i = i + 2;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                text = Encoding.BigEndianUnicode.GetString(b3);
                            }
                            //char[] c = text.ToCharArray();
                            //byte[] b = new byte[c.Length];
                            //for (int i = 0; i < c.Length; i++)
                            //{
                            //    b[i] = c[i];
                            //}
                            //string s = Encoding.BigEndianUnicode.GetString(b);
                        }
                        catch (Exception ex)
                        {
                            Logger.Write(ex);
                        }
                        tb.Addtb_ReciveListRow(msg.getOriginator(), cDate.ToString(), msg.getGatewayId(), text);
                        DbRules.Instance.UpdateReciveList();
                        tb.AcceptChanges();
                    }));
                    Debug.WriteLine(">>> New Inbound message detected from Gateway: " + gateway.getGatewayId());
                }
                else if (msgType == org.smslib.Message.MessageTypes.STATUSREPORT) Debug.WriteLine(">>> New Inbound Status Report message detected from Gateway: " + gateway.getGatewayId());


                try
                {
                    // Uncomment following line if you wish to delete the message upon arrival.
                    gateway.deleteMessage(msg);
                }
                catch (Exception ex)
                {
                    Logger.Write(ex);
                }
                //更新接收数量
                smsdbDataSet.tb_SetDataTable tbSet = null;
                SetManagerForm f2 = ((SetManagerForm)FormManager.Instance.GetForm("SetManagerItem"));
                f2.Invoke(new System.Windows.Forms.MethodInvoker(() =>
                {
                    tbSet = DbRules.Instance.GetSetInfo();
                    for (int i = 0; i < tbSet.Rows.Count; i++)
                    {
                        if (tbSet[i].PortNum == msg.getGatewayId())
                        {
                            tbSet[i].ReciveCount = tbSet[i].ReciveCount + 1;
                        }
                    }
                    DbRules.Instance.UpdateSetInfo();
                    tbSet.AcceptChanges();
                }));
                SmsHelper.Instance.Listening = false;//我用完了，ui可以关闭串口了。  
            }

            catch (Exception ex)
            {
                Logger.Write(ex);

            }
        }
    }
    public class GatewayStatusNotification : IGatewayStatusNotification
    {
        public void process(AGateway gateway, org.smslib.AGateway.GatewayStatuses oldStatus, org.smslib.AGateway.GatewayStatuses newStatus)
        {
            //if (SmsHelper.Instance.Closing) return;//如果正在关闭，忽略操作，直接返回，尽快的完成串口监听线程的一次循环  
            //try
            //{
            //    SmsHelper.Instance.Listening = true;//设置标记，说明我已经开始处理数据，一会儿要使用系统UI的。  
            //    SetManagerForm f2 = ((SetManagerForm)FormManager.Instance.GetForm("SetManagerItem"));
            //    f2.BeginInvoke(new System.Windows.Forms.MethodInvoker(() =>
            //    {
            //        f2.ModifyDeviceState(gateway.getGatewayId(), newStatus.toString());
            //    }));
            //}
            //finally
            //{
            //    SmsHelper.Instance.Listening = false;//我用完了，ui可以关闭串口了。  
            //}
            Console.WriteLine("端口状态改变" + gateway.getGatewayId() + " " + oldStatus.toString() + " " + newStatus.toString());
        }
    }
    public class MyRouter : org.smslib.routing.Router
    {
        public override void customRouting(OutboundMessage msg)
        {
            //判断发送数量上限
            if (msg.getText() == SmsHelper.IsCallNum)
            {
                getAllowed().addAll(getCandidates());
                return;
            }
            smsdbDataSet.tb_SetDataTable tb = DbRules.Instance.GetSetInfo();
            TimeSpan hourSpan = new TimeSpan(1, 0, 0);
            for (int i = 0; i < getCandidates().size(); i++)
            {
                bool canUse = true;
                for (int j = 0; j < tb.Rows.Count; j++)
                {
                    if (tb[j].PortNum == ((AGateway)getCandidates().get(i)).getGatewayId())
                    {
                        if (SmsHelper.Instance.ResList.ContainsKey(tb[j].PortNum) && SmsHelper.Instance.ResList[tb[j].PortNum].SendCount > 0)
                        {
                        }
                        else
                        {
                            SmsHelper.Instance.ResList[tb[j].PortNum].FirstSendTime = DateTime.Now;
                            SmsHelper.Instance.ResList[tb[j].PortNum].SendCount = 1;
                        }
                        //判断发送数量上限
                        if (tb[j].State != "启用" || (tb[j].SuccessCount + SmsHelper.Instance.ResList[tb[j].PortNum].SuccCount >= tb[j].MaxCount && tb[j].MaxCount != 0))
                        {
                            canUse = false;
                        }
                        if (tb[j].SetType == "集中发送") //集中发送
                        {
                            //判断发送速度
                            //if (tb[j].Speed != 0 && SmsHelper.Instance.ResList[tb[j].PortNum].SendCount >= tb[j].Speed)
                            //{

                            //    smsdbDataSet.tb_SendedListRow row = DbRules.Instance.GetLastSpeedCountRowInfo(tb[j].Speed, tb[j].PortNum);
                            //    if (row != null)
                            //    {
                            //        if (DateTime.Now - DateTime.Parse(row.SendTime) < hourSpan)
                            //        {
                            //            canUse = false;
                            //        }
                            //    }
                            //    else
                            //    {
                            //        canUse = false;
                            //    }
                            //}
                        }
                        else if (tb[j].SetType == "平均发送") //平均发送
                        {
                            if (SmsHelper.Instance.ResList.ContainsKey(tb[j].PortNum) && SmsHelper.Instance.ResList[tb[j].PortNum].SendCount > 0 && tb[j].Speed > 0)
                            {
                                TimeSpan aHour = new TimeSpan(0, 0, 3600 / tb[j].Speed * SmsHelper.Instance.ResList[tb[j].PortNum].SendCount);
                                if (DateTime.Now - SmsHelper.Instance.ResList[tb[j].PortNum].FirstSendTime < aHour)
                                {
                                    canUse = false;
                                }
                            }
                            else
                            {
                                SmsHelper.Instance.ResList[tb[j].PortNum].FirstSendTime = DateTime.Now;
                                SmsHelper.Instance.ResList[tb[j].PortNum].SendCount = 1;
                            }



                            //smsdbDataSet.tb_SendedListRow row = DbRules.Instance.GetLastSpeedCountRowInfo(1, tb[j].PortNum);
                            //if (tb[j].Speed != 0)
                            //{
                            //    TimeSpan aHour = new TimeSpan(0, 0, 3600 / tb[j].Speed);
                            //    if (row != null)
                            //    {
                            //        if (DateTime.Now - DateTime.Parse(row.SendTime) <= aHour)
                            //        {
                            //            canUse = false;
                            //        }
                            //    }
                            //    java.util.Collection sendColl = SmsHelper.Instance.srv.getQueueManager().getPendingMessages(tb[j].PortNum);
                            //    java.util.Iterator it = sendColl.iterator();
                            //    ;
                            //    while (it.hasNext())
                            //    {
                            //        OutboundMessage outMess = (OutboundMessage)it.next();
                            //        java.util.Date jd = outMess.getDate();
                            //        DateTime dt = DateTime.Parse(jd.toLocaleString());
                            //        if (DateTime.Now - dt <= (aHour - new TimeSpan(0, 0, 5)))
                            //        {
                            //            canUse = false;
                            //        }
                            //    }
                            //}
                        }
                    }
                }
                if (canUse)
                {

                    getAllowed().add(getCandidates().get(i));

                }
                else
                {
                }
            }
            //base.customRouting(msg);
        }
    }
    public class MyQueueSendingNotification : IQueueSendingNotification
    {
        public void process(AGateway ag, OutboundMessage om)
        {
            if (SmsHelper.Instance.Closing) return;//如果正在关闭，忽略操作，直接返回，尽快的完成串口监听线程的一次循环  


            try
            {
                SmsHelper.Instance.Listening = true;//设置标记，说明我已经开始处理数据，一会儿要使用系统UI的。
                if (om.getText() == SmsHelper.IsCallNum)
                {
                    //frmTrueTel sfrmTrueTelForm = ((frmTrueTel)FormManager.Instance.GetForm("TrueNumItem"));
                    //sfrmTrueTelForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
                    //{
                    //    sfrmTrueTelForm.DeteleItem(om.getId());
                    //}));
                    return;
                }
                SmsHelper.Instance.RemoveQueueByID(om.getId());
                sendListForm sendListForm = ((sendListForm)FormManager.Instance.GetForm("SendListItem"));
                //sendListForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
                //{
                //    sendListForm.DeleteItem(om.getId());
                //    DbRules.Instance.SetSendingCount(ag.getGatewayId(), 1);
                //}));
                smsdbDataSet.tb_SendedListDataTable tb = null;
                SendedListForm f = ((SendedListForm)FormManager.Instance.GetForm("SendRecodItem"));
                f.Invoke(new System.Windows.Forms.MethodInvoker(() =>
                {
                    tb = DbRules.Instance.GetSendedListTable();
                    string sendState = "未知";
                    DateTime cDate = DateTime.Now;
                    tb.Addtb_SendedListRow(sendState, om.getRecipient(), cDate.ToString(), om.getGatewayId(), om.getText());
                    DbRules.Instance.UpdateSendedList();
                    tb.AcceptChanges();
                }));

            }
            catch (Exception ex)
            {
                Logger.Write(ex);
            }
            finally
            {
                SmsHelper.Instance.Listening = false;//设置标记，说明我已经开始处理数据，一会儿要使用系统UI的。
            }
        }
    }
    public class MyBalance : LoadBalancer
    {
        public override AGateway balance(OutboundMessage msg, java.util.Collection candidates)
        {
            AGateway ag = base.balance(msg, candidates);
            string ggid = ag.getGatewayId();
            SmsHelper.Instance.ResList[ggid].SuccCount++;
            //smsdbDataSet.tb_SetDataTable tbSet = null;
            //SetManagerForm f2 = ((SetManagerForm)FormManager.Instance.GetForm("SetManagerItem"));
            //f2.Invoke(new System.Windows.Forms.MethodInvoker(() =>
            //{
            //    tbSet = DbRules.Instance.GetSetInfo();
            //    for (int k = 0; k < tbSet.Rows.Count; k++)
            //    {
            //        if (tbSet[k].PortNum == ggid)
            //        {
            //            Console.WriteLine("端口" + ggid + "加1");
            //            tbSet[k].SuccessCount = tbSet[k].SuccessCount + 1;

            //            break;
            //        }
            //    }

            //}));
            return ag;
        }
    }
}
